package eg.backend.repository.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import eg.backend.base.PermissionType;
import eg.backend.base.repository.EntityRepositoryImpl;
import eg.backend.domain.Dimension;
import eg.backend.domain.User;
import eg.backend.repository.DimensionRepository;
import eg.backend.util.Constants;

public class DimensionRepositoryImpl extends EntityRepositoryImpl<Dimension, String> implements DimensionRepository{
	@Override
	public Dimension get(String identifier) {
		String queryName = "Dimension.getByKey";
		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("encodedKey", identifier);
		Dimension dimension = null;
		try {
			dimension = this.getByNamedQuery(queryName, queryParams);
		} catch (Exception e) {
			System.out.println("exception in get dimension with key " + identifier);
			e.printStackTrace();
		}
		return dimension;
	}

	public List<Dimension> findUserRootDimensions(String user) {
		String queryName = "Dimension.findUserRootDimensions";
		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("user", user);
		List<Dimension> result = this.findByNamedQuery(queryName, queryParams);
		return result;
	}

	public List<Dimension> findSystemRootDimensions() {
		String queryName = "Dimension.findSystemRootDimensions";
		Map<String, Object> queryParams = new HashMap<String, Object>();
		return this.findByNamedQuery(queryName, queryParams);
	}

	public List<Dimension> findAvailByParent(String parent,
			String user, String userName) {
		List<Dimension> result = new ArrayList<Dimension>();
		String queryName = "Dimension.findUserAvailByParent";
		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("parent", parent);
		queryParams.put("user", user);
		result.addAll(findByNamedQuery(queryName, queryParams));
		if(!Constants.USER_SYSTEM_NAME.equals(userName)) {
			queryName = "Dimension.findSystemAvailByParent";
			queryParams.clear();
			queryParams.put("parent", parent);
			result.addAll(findByNamedQuery(queryName, queryParams));
		}
		return result;
	}
	
	public void deleteRootDimension(String rootDimension) {
		String queryName = "Dimension.deleteRootDimension";
		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("rootDimension", rootDimension);
		this.update(queryName, queryParams);
	}

	public List<String> findDescendantIds(String position,
			String rootDimension, String user) {
		List<String> ids = new ArrayList<String>();
		String queryName = "Dimension.findDescendantIdsOfUser";
		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("rootDimension", rootDimension);
		queryParams.put("user", user);
		queryParams.put("position", position);
		List<String> users = baseDao.findByNamedQuery(queryName, Integer.MAX_VALUE, queryParams);
		ids.addAll(users);
		
		queryName = "Dimension.findDescendantIdsOfSystem";
		queryParams = new HashMap<String, Object>();
		queryParams.put("rootDimension", rootDimension);
		queryParams.put("position", position);
		List<String> systems = baseDao.findByNamedQuery(queryName, Integer.MAX_VALUE, queryParams);
		ids.addAll(systems);
		
		return ids;
	}

	public List<Dimension> findDescendants(String position,
			String rootDimension, String user) {
		String queryName = "Dimension.findDescendants";
		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("rootDimension", rootDimension);
		queryParams.put("user", user);
		queryParams.put("position", position);
		return this.findByNamedQuery(queryName, queryParams);
	}

	public List<Dimension> findSharedDimensions(
			List<PermissionType> permissions, User user) {
		// TODO Auto-generated method stub
		return null;
	}

	public List<Dimension> findSharedDimensionsByParent(Dimension parent,
			List<PermissionType> permissions, User user) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Dimension> loadAll() {
		List<Dimension> result = super.loadAll();
		result.size();
		return result;
	}

	public List<String> findSystemCategory(String position) {
		String queryName = "Dimension.findSystemCategory";
		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("position", position);
		return baseDao.findByNamedQuery(queryName, Integer.MAX_VALUE, queryParams);
	}

	public List<String> findUserCategory(String user, String position) {
		String queryName = "Dimension.findUserCategory";
		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("position", position);
		queryParams.put("user", user);
		return baseDao.findByNamedQuery(queryName, Integer.MAX_VALUE, queryParams);
	}

	public Dimension eagerGet(String key) {
		Dimension dimension = this.get(key);
		dimension.getChildren().size();
		return dimension;
	}

	public List<Dimension> find(String user) {
		String queryName = "Dimension.find";
		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("user", user);
		return this.findByNamedQuery(queryName, queryParams);
	}

	public void deleteById(String id) {
		String queryName = "Dimension.delete";
		Map<String, Object> queryParams = new HashMap<String, Object>();
		queryParams.put("id", id);
		int result = baseDao.updateByNamedQuery(queryName, queryParams);
		System.out.println("result: " + result);
	}

}
